﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

namespace Gameplay.PVE
{
    public class LightMapApply : MonoBehaviour
    {
        public static readonly int PROBE_POSITION_PROPERTY_ID = Shader.PropertyToID("_ProbePosition");
        public static readonly int PROBE_BOXSIZE_PROPERTY_ID = Shader.PropertyToID("_BoxSize");
        public static readonly int PROBE_BOXOFFSET_PROPERTY_ID = Shader.PropertyToID("_BoxOffset");
        public static readonly int PROBE_ROTATION_PROPERTY_ID = Shader.PropertyToID("_BoxRotation");
        public static readonly int PROBE_BOXSPHERE_RADIUS_PROPERTY_ID = Shader.PropertyToID("_BoxSphereRadius");

        public PrefabMeshRenderCache MeshRenderCache;

        public List<MeshRendererData> MeshRendererDatas;

        public ReflectionProbe ReflectionProbe;

        private bool IsInitialized;

        private void Start()
        {
            Apply();
            IsInitialized = true;
        }

        private void OnEnable()
        {
            // 创建的时候位置和旋转还没有设置，先不应用，等Start的时候做
            if (!IsInitialized)
                return;

            Apply();
        }

        public void Apply()
        {
            if (MeshRenderCache && MeshRenderCache.MeshRenderers != null)
            {
                SetLightMap();
                SetReflectionProbe();
            }
        }

        private void SetReflectionProbe()
        {
#if UNITY_EDITOR
            if (ReflectionProbe == null)
            {
                ReflectionProbe = GetComponentInChildren<ReflectionProbe>();
            }            
#endif

            if (ReflectionProbe == null)
                return;

            var reflectionProbeTransform = ReflectionProbe.transform;
            var trs = Matrix4x4.TRS(reflectionProbeTransform.position, Quaternion.Inverse(reflectionProbeTransform.rotation), Vector3.one);
            Vector4 position = reflectionProbeTransform.position;
            // set weight
            position.w = 1;

            foreach (var meshRenderer in MeshRenderCache.MeshRenderers)  
            {
                if(meshRenderer==null || meshRenderer.reflectionProbeUsage == ReflectionProbeUsage.Off)
                    continue;

                var propertyBlock = new MaterialPropertyBlock();
                meshRenderer.GetPropertyBlock(propertyBlock);
                propertyBlock.SetVector(PROBE_POSITION_PROPERTY_ID, position);
                propertyBlock.SetVector(PROBE_BOXSIZE_PROPERTY_ID, ReflectionProbe.size);
                propertyBlock.SetVector(PROBE_BOXOFFSET_PROPERTY_ID, ReflectionProbe.center);
                propertyBlock.SetMatrix(PROBE_ROTATION_PROPERTY_ID, trs);
                //propertyBlock.SetFloat(PROBE_BOXSPHERE_RADIUS_PROPERTY_ID, probe.GetComponent<HReflectionProbeBakeRotated>().sphereRadius);
                meshRenderer.SetPropertyBlock(propertyBlock);
            }
        }

        private void SetLightMap()
        {
            if (MeshRendererDatas == null)
                return;

            for (int i = 0; i < MeshRenderCache.MeshRenderers.Count; i++)
            {
                if (i > MeshRendererDatas.Count - 1)
                {
                    break;
                }

                var mr = MeshRenderCache.MeshRenderers[i];
                if (mr)
                {
                    mr.lightmapIndex = MeshRendererDatas[i].lightmapIndex;
                    mr.lightmapScaleOffset = MeshRendererDatas[i].lightmapScaleOffset;
                }
               
            }
        }
    }
}
